﻿using System;

namespace DelegateAndEvent
{
    // 定义一个事件类
    public class MyEvent
    {
        // 定义一个委托
        public delegate void MyDelegate();
        // 定义一个事件
        public event MyDelegate MyDelegateEvent;
        // 定义一个触发事件的函数
        public void OnMyDelegateEvent()
        {
            // 判断事件是否非空
            if(MyDelegateEvent !=null)
            {
                // 执行事件
                MyDelegateEvent();
            }
            //MyDelegateEvent?.Invoke(); // 简化的判断和执行
        }
    }

    class Program
    {
        // 输出一串字符
        public static void PutOutChar()
        {
            Console.WriteLine("I was fired");
        }

        // 输出第二串字符
        public static void PutOutChar2()
        {
            Console.WriteLine("I was fired222222");
        }

        static void Main(string[] args)
        {
            // 实例化MyEvent类
            MyEvent myEvent = new MyEvent();
            // 注册一个事件
            myEvent.MyDelegateEvent += new MyEvent.MyDelegate(PutOutChar);
            myEvent.MyDelegateEvent += new MyEvent.MyDelegate(PutOutChar2);
            // 执行触发事件的函数
            Console.WriteLine("执行绑定了两个事件后的函数");
            myEvent.OnMyDelegateEvent();
            // 解绑一个事件
            myEvent.MyDelegateEvent -= new MyEvent.MyDelegate(PutOutChar);
            // 再次执行触发事件的函数
            Console.WriteLine("执行解绑了一个事件后的函数");
            myEvent.OnMyDelegateEvent();
            Console.ReadKey();
        }
    }
}
/*
 
事件是拥有可以注册和解绑方法（函数）的功能。

虽然事件和委托看起来有点绕，只要捋清楚事件和委托的关系，就会很容易理解。

委托是一个类，事件则是委托类中的一个对象，该对象是能够把其他方法注册到委托类中的一个事件（如果觉得有点绕，可以忽略这句话）。

事件和函数的关系：事件具有可以注册多个函数（和解绑函数）的功能，而函数如果要注册和解绑其他在其主体上运行的函数则需要改动该函数本体的代码，这就是区别。

以下代码的大致流程：定义一个新类（事件类）--》类中声明委托--》由委托类又声明事件--》再定义触发事件的函数--》函数主体中执行事件--》在主函数中实例化事件类--》进而调用事件类中的事件对象--》事件对象再注册（+=）两个方法--》再执行事件类中触发事件的那个函数--》再解绑其中一个方法--》再次执行事件类中触发事件的函数。

由此可见：事件是拥有可以注册和解绑方法（函数）的功能。

 */